using System;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;

namespace Microsoft.WowAddonStudio.Lua.RuntimeService.ToolWindows
{
	/// <summary>
	/// 
	/// </summary>
	public partial class WoWBenchControl
	{

		#region Key event handlers

		/// <summary>
		/// Handles KeyDown event raised by Output control.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void txtOutput_KeyDown(object sender, KeyEventArgs e)
		{
			HandleOutputKeyDown(e);
		}

		/// <summary>
		/// Handles KeyUp event raised by Output control.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void txtOutput_KeyUp(object sender, KeyEventArgs e)
		{
			HandleOutputKeyUp(e);
		}

		/// <summary>
		/// Handles KeyPress event raised by Output control.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void txtOutput_KeyPress(object sender, KeyPressEventArgs e)
		{
			HandleOutputKeyPress(e);
		}

		/// <summary>
		/// Handles KeyDown event raised by Output control.
		/// </summary>
		/// <param name="arg">The KeyEventArgs.</param>
		protected virtual void HandleOutputKeyDown(KeyEventArgs arg)
		{
			arg.SuppressKeyPress = ReadOnly;
			if(!ReadOnly)
				//Handle <Enter> key
				if (arg.KeyCode == Keys.Enter)
				{
					ExecuteLuaCommandOnDisplay();
					arg.Handled = true;
				}
				//Handle <Backspace> and <Delete> keys
				else if (arg.KeyCode == Keys.Back || arg.KeyCode == Keys.Delete)
				{
					bool isLastLine = IsLastLine();
					if (isLastLine)
						arg.SuppressKeyPress = woWBenchController.BufferPosition >= txtOutput.SelectionStart;
					else
						arg.SuppressKeyPress = !isLastLine;
				}
				//Handle CTRL + <Break> key
				else if (arg.KeyCode == Keys.Pause && arg.Control)
				{
					WoWBenchController.ExecuteCommand("%BREAK%");
				}
				//Handle CTRL + <V> key - Paste command
				else if (arg.KeyCode == Keys.V && arg.Control)
				{
					SetInputLine();
					txtOutput.SelectedText = Clipboard.GetText();
					HandleOutputKeyPress(string.Empty);
					arg.SuppressKeyPress = true;
				}
				else
				{
					bool isCommandHistoryKey = false;
					string newCommand = string.Empty;
					//Handle arrow keys
					switch (arg.KeyCode)
					{
						case Keys.Up:
							{
								isCommandHistoryKey = true;
								newCommand = WoWBenchController.CommandHistory.Previous.GetCommand();
								break;
							}
						case Keys.Down:
							{
								isCommandHistoryKey = true;
								newCommand = WoWBenchController.CommandHistory.Next.GetCommand();
								break;
							}
						case Keys.Escape:
							{
								isCommandHistoryKey = true;
								newCommand = string.Empty;
								break;
							}
					}
					if (isCommandHistoryKey)
					{
						SetTextInLine(newCommand, txtOutput.Lines.Length - 1);
						arg.Handled = true;
						arg.SuppressKeyPress = true;
						return;
					}
					//Handle all other unhandled keys
					if (txtOutput.Lines.Length > 0)
					{
						int index = txtOutput.SelectionStart - txtOutput.GetFirstCharIndexFromLine(txtOutput.Lines.Length - 1);
						arg.SuppressKeyPress = index < 0;
					}
				}
		}

		/// <summary>
		/// Handles KeyUp event raised by Output control.
		/// </summary>
		/// <param name="arg">The KeyEventArgs.</param>
		/// <remarks>Inherited class can override this handler.</remarks>
		protected virtual void HandleOutputKeyUp(KeyEventArgs arg)
		{
			//Do not handle.
		}

		/// <summary>
		/// Handles KeyPress event raised by Output control.
		/// </summary>
		/// <param name="arg">The KeyPressEventArgs.</param>
		/// <remarks>Inherited class can override this handler.</remarks>
		protected virtual void HandleOutputKeyPress(KeyPressEventArgs arg)
		{
			HandleOutputKeyPress(arg.KeyChar.ToString());
			arg.Handled = false;
		}

		/// <summary>
		/// Handles KeyPress event raised by Output control.
		/// </summary>
		/// <param name="key">The pressed character.</param>
		/// <remarks>Inherited class can override this handler.</remarks>
		protected virtual void HandleOutputKeyPress(string key)
		{
			string line = txtOutput.Lines[txtOutput.Lines.Length - 1];
			try
			{
				int index = txtOutput.SelectionStart - txtOutput.GetFirstCharIndexFromLine(txtOutput.Lines.Length - 1);
				if (index > -1)
					line = line.Insert(index, key);
			}
			catch (Exception ex)
			{
				Trace.WriteLine(ex);
				line = txtOutput.Lines[txtOutput.Lines.Length - 1];
			}
			WoWBenchController.WowBenchCommand.Add(line);
		}

		#endregion

	}
}